package com.msh.http.controller;

import com.google.common.base.Strings;
import com.msh.common.VMSystem;
import com.msh.config.ConsulConfig;
import com.msh.exception.LogicException;
import com.msh.feignService.OrderService;
import com.msh.feignService.VMService;
import com.msh.service.WxService;
import com.msh.utils.DistributedLock;
import com.msh.viewmodel.OrderViewModel;
import com.msh.viewmodel.Pager;
import com.msh.viewmodel.RequestPay;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import javax.management.Query;
import java.time.Duration;
import java.time.LocalDate;

@RestController
@RequestMapping("/order")
@Slf4j
public class OrderController {

    @Autowired
    private WxService wxService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private VMService vmService;
    @Autowired
    private ConsulConfig config;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;


    /**
     * 获取openId
     * @param jsCode
     * @return
     */
    @GetMapping("/openid/{jsCode}")
    public String getOpenid(@PathVariable String jsCode){
        return "wqdqdqdqdqd";//返回固定的，毕设演示使用
        //return wxService.getOpenId(jsCode);
    }


    @PostMapping("/requestPay")
    public String requestPay(@RequestBody RequestPay requestPay) {
        if (!vmService.hasCapacity(requestPay.getInnerCode(), Long.parseLong(requestPay.getSkuId()))) {
            throw new LogicException("该商品已售空");
        }
        //如果openId为空，则根据jsCode生成
        if (Strings.isNullOrEmpty(requestPay.getOpenId())) {
            //requestPay.setOpenId(wxService.getOpenId(requestPay.getJsCode()));
            requestPay.setOpenId("wqdqdqdqdqd");
        }
        //分布式锁，机器同一时间只能处理一次出货
        DistributedLock lock = new DistributedLock(config.getConsulRegisterHost(),config.getConsulRegisterPort());
        DistributedLock.LockContext lockContext = lock.getLock(requestPay.getInnerCode(), 60);
        if (!lockContext.isGetLock()) {
            throw new LogicException("机器出货中请稍后再试");
        }
        //将session存入redis,方便分布式释放锁
        redisTemplate.boundValueOps(VMSystem.VM_LOCK_KEY_PREF + requestPay.getInnerCode())
                .set(lockContext.getSession(), Duration.ofSeconds(60));
        String responseData = orderService.requestPay(requestPay);
        if (Strings.isNullOrEmpty(responseData)) {
            throw new LogicException("微信支付接口调用失败");
        }
        return responseData;
    }

    /**
     * 取消订单
     * @param innerCode
     */
    @GetMapping("/cancelPay/{innerCode}/{orderNo}")
    public void cancel(@PathVariable String innerCode,@PathVariable String orderNo){
        DistributedLock lock = new DistributedLock(
                config.getConsulRegisterHost(),
                config.getConsulRegisterPort());
        String sessionId = redisTemplate.boundValueOps(VMSystem.VM_LOCK_KEY_PREF + innerCode).get();
        if(Strings.isNullOrEmpty(sessionId)) return;
        try {
            lock.releaseLock(sessionId);
            orderService.cancel(orderNo);
        }catch (Exception ex){
            log.error("取消订单出错",ex);
        }
    }

    @GetMapping("/search")
    public Pager<OrderViewModel> search(@RequestParam(value = "pageIndex",required = false,defaultValue = "1") Integer pageIndex,
                                        @RequestParam(value = "pageSize",required = false,defaultValue = "10") Integer pageSize,
                                        @RequestParam(value = "orderNo",required = false) String orderNo,
                                        @RequestParam(value = "openId") String openId,
                                        @RequestParam(value = "startDate") @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate start,
                                        @RequestParam(value = "endDate") @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end
                                        ) {
        return orderService.search(pageIndex,pageSize,orderNo,openId,start,end);
    }
}